package com.effectiv.gooruda.rest.service.api;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import lombok.Getter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;

import com.effectiv.gooruda.rest.docs.annotation.Api;
import com.effectiv.gooruda.rest.docs.annotation.ApiBodyObject;
import com.effectiv.gooruda.rest.docs.annotation.ApiHeaders;
import com.effectiv.gooruda.rest.docs.annotation.ApiHeader;
import com.effectiv.gooruda.rest.docs.annotation.ApiMethod;
import com.effectiv.gooruda.rest.docs.annotation.ApiParam;
import com.effectiv.gooruda.rest.docs.annotation.ApiResponseObject;
import com.effectiv.gooruda.rest.docs.pojo.ApiVerb;
import com.effectiv.gooruda.rest.domain.Permission;
import com.effectiv.gooruda.rest.ext.ExtResponse;
import com.effectiv.gooruda.rest.ext.SecurityContextHolder;

@Path("/permission")
@Api(name = "Permission API", description = "Permission management API.")
public abstract class PermissionService {
	
	private final String COLLECTION_BASE = "c_app_permission_";
	
	@Getter
	@Autowired
	private MongoTemplate template;
	
	protected String getCollection(){
		return COLLECTION_BASE + SecurityContextHolder.get().getId();
	}
	
	protected void throwException(int errorCode, String errorMessage){
		ExtResponse extRes = new ExtResponse();
		extRes.setErrorCode(errorCode);
		extRes.setMessage(errorMessage);
		
		ResponseBuilder resBuilder = Response.status(Status.BAD_REQUEST);
		resBuilder.entity(extRes);
		
		throw new WebApplicationException(resBuilder.build());
	}
	
	/**
	 * Save a new permission
	 * @param p
	 * @return
	 */
	
	@ApiMethod(path = "/api/permission", verb = ApiVerb.POST, description = "Save permission details.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	@POST	
	@Produces(MediaType.APPLICATION_JSON)
	public abstract @ApiResponseObject Response create(@ApiBodyObject Permission p);
	
	
	/**
	 * Find a permission by name
	 * @param name
	 * @return
	 */
	@ApiMethod(path = "/api/permission/findbyname/{name}", verb = ApiVerb.GET, description = "Find a permission by name.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	@Path("/findbyname/{name}")
	@GET	
	@Produces(MediaType.APPLICATION_JSON)
	public abstract @ApiResponseObject Response findByName(@PathParam("name") @ApiParam(name="name", description="Permission name") String name);
	
	
	/**
	 * Find a permission by id
	 * @param id
	 * @return
	 */
	@ApiMethod(path = "/api/permission/findone/{id}", verb = ApiVerb.GET, description = "Find a permission by id.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	@Path("/findone/{id}")
	@GET	
	@Produces(MediaType.APPLICATION_JSON)
	public abstract Response findOne(@PathParam("id") @ApiParam(name="id", description="Permission id") String id);
	
	public abstract Permission findByNameInternal(String p);
}
